require 'time'

#
# CPL Assignment 2
# Tim Caljé, Jeroen De Raedt & Jorick Van Aken
#
class Flight
  def initialize(id, departureTime, duration, date, connectionDao, bookingDao)
    @id = id
    @departureTime = Time.parse(date + " " + departureTime)
    @arrivalTime = @departureTime + convertDurationToSec(duration)
    
    @connectionDao = connectionDao
    @bookingDao = bookingDao
  end
  
  def id
    @id
  end
  
  def departureTime
    @departureTime
  end
  
  def arrivalTime
    @arrivalTime
  end
  
  def departure
    if(@departure == nil) 
      fillAirports()
    end
    @departure
  end
  
  def arrival
    if(@arrival == nil) 
      fillAirports()
    end
    @arrival
  end
  
  def airline
    @airline ||= @connectionDao.getAirlineById(@id.slice(0..2))
  end
  
  def date
    departureTime.to_s.slice(0..9)
  end
  
  def to_s
    "Flight: #{id} #{airline}
     \t From #{departure} to: #{arrival} 
     \t Departure: #{departureTime} arrival: #{arrivalTime}
     \t Available economy seats: #{nbFreeEconomy} ($ #{priceEconomy}) 
     \t Available business seats: #{nbFreeBusinessClass} ($ #{priceBusinessClass})
     \t Available first class seats: #{nbFreeFirstClass} ($ #{priceFirstClass})"
  end
  
  def nbFreeSeats(type)
    case type
    when SeatType::BUSINESS
      return nbFreeBusinessClass
    when SeatType::ECONOMY
      return nbFreeEconomy
    when SeatType::FIRST_CLASS
      return nbFreeFirstClass
    else
      return self.nbFreeBusinessClass() + self.nbFreeEconomy() + self.nbFreeFirstClass()
    end
  end
  
  def priceSeats(type)
    case type
    when SeatType::BUSINESS
      return priceBusinessClass
    when SeatType::ECONOMY
      return priceEconomy
    when SeatType::FIRST_CLASS
      return priceFirstClass
    else
      return 0
    end
  end
  
  #returns the price by placing all the persons (starting from economy to first class)
  def placePersons(amountPersons)
    price = 0.0
    
    if nbFreeEconomy >= amountPersons
      return amountPersons * priceEconomy
    else
      amountEconomy = nbFreeEconomy
      amountPersons -= amountEconomy
      price += amountEconomy * priceEconomy
      if nbFreeBusinessClass >= amountPersons
        amountBusiness = amountPersons
        price += amountBusiness * priceBusinessClass
        return price
      else
        amountBusiness = nbFreeBusinessClass
        amountPersons -= amountBusiness
        if nbFreeFirstClass >= amountPersons
          amountFirstClass = amountPersons
          price += amountFirstClass * priceFirstClass
          return price
        else
          raise Exception, 'Unable to place all the passengers in this flight!'
        end
      end
    end
  end
  
  def nbFreeBusinessClass
    if @nbFreeBusiness == nil
      fillBusinessDetails()
    end
    @nbFreeBusiness
  end
  
  def priceBusinessClass
    if @priceBusiness == nil
        fillBusinessDetails()
      end
    @priceBusiness
  end

  def nbFreeFirstClass
    if @nbFreeFirstClass == nil
      fillFirstClassDetails()
    end
    @nbFreeFirstClass
  end
  
  def priceFirstClass
    if @priceFirstClass == nil
        fillFirtClassDetails()
      end
    @priceFirstClass
    end
  
  def nbFreeEconomy
    if @nbFreeEconomy == nil
      fillEconomyDetails()
    end
    @nbFreeEconomy
  end
  
  def priceEconomy
    if @priceEconomy == nil
        fillEconomyDetails()
      end
    @priceEconomy
  end
  
  private 
  def fillAirports() 
    results = @connectionDao.getAirportsByFlightNr(@id)
    @departure ||= results[0]
    @arrival ||= results[1]
  end
  
 private
 def fillBusinessDetails()
   results = @bookingDao.getBusinessDetailsForFlight(id, departureTime.strftime('%Y/%m/%d'))
   @nbFreeBusiness ||= results[0]
   @priceBusiness ||= results[1]
 end
 
 private
 def fillFirstClassDetails()
   results = @bookingDao.getFirstClassDetailsForFlight(id, departureTime.strftime('%Y/%m/%d'))
   @nbFreeFirstClass ||= results[0]
   @priceFirstClass ||= results[1]
 end
 
 private
 def fillEconomyDetails()
   results = @bookingDao.getEconomyDetailsForFlight(id, departureTime.strftime('%Y/%m/%d'))
   @priceEconomy = results[1]
   @nbFreeEconomy = results[0]
 end
 
 def convertDurationToSec(duration)
   hours = duration.slice(0..1).to_i
   minutes = duration.slice(3..4).to_i
   return (hours *3600) + minutes * 60
 end
  
end